package com.ybl.store.backend.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ybl.store.backend.dao.entity.ManagerDO;
import com.ybl.store.backend.dao.entity.StoreDO;
import com.ybl.store.backend.dao.mapper.ManagerMapper;
import com.ybl.store.backend.dao.mapper.StoreMapper;
import com.ybl.store.backend.dto.req.ManagerSaveReqDTO;
import com.ybl.store.backend.dto.req.ManagerUpdateReqDTO;
import com.ybl.store.backend.dto.resp.ListRespDTO;
import com.ybl.store.backend.dto.resp.ManagerPageRespDTO;
import com.ybl.store.backend.dto.resp.ManagerRealNameRespDTO;
import com.ybl.store.backend.dto.resp.ManagerSaveRespDTO;
import com.ybl.store.backend.service.ManagerService;
import com.ybl.store.backend.service.UserService.UserService;
import com.ybl.store.common.constant.DelFlag;
import com.ybl.store.common.convention.errorcode.BaseErrorCode;
import com.ybl.store.common.convention.exception.ClientException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;

@Service
@RequiredArgsConstructor
public class ManagerServiceImpl extends ServiceImpl<ManagerMapper, ManagerDO> implements ManagerService {

    private final StoreMapper storeMapper;

    private final UserService userService;
    
    @Override
    public ManagerSaveRespDTO saveManager(ManagerSaveReqDTO requestParam) {
        StoreDO storeDO = storeMapper.selectById(requestParam.getStoreId());

        if (storeDO == null) {
            throw new ClientException(BaseErrorCode.STORE_NULL_ERROR);
        }

        ManagerDO managerDO = BeanUtil.toBean(requestParam, ManagerDO.class);
        String username = userService.createRandomUsername();
        String password = userService.createRandomPassword();

        managerDO.setUsername(username);
        managerDO.setPassword(password);

        int result = baseMapper.insert(managerDO);

        if (result < 1) {
            throw new ClientException(BaseErrorCode.MANAGER_SAVE_ERROR);
        }

        return ManagerSaveRespDTO
                .builder()
                .username(username)
                .password(password)
                .build();
    }

    @Override
    public void deleteManagerById(Long id) {
        int result = baseMapper.deleteById(id);

        if (result < 1) {
            throw new ClientException(BaseErrorCode.MANAGER_DELETE_ERROR);
        }
    }

    @Override
    public void updateManager(ManagerUpdateReqDTO requestParam) {
        StoreDO storeDO = storeMapper.selectById(requestParam.getStoreId());

        if (storeDO == null) {
            throw new ClientException(BaseErrorCode.STORE_NULL_ERROR);
        }

        int result = baseMapper.updateById(BeanUtil.toBean(requestParam, ManagerDO.class));

        if (result < 1) {
            throw new ClientException(BaseErrorCode.MANAGER_UPDATE_ERROR);
        }
    }

    @Override
    public ManagerPageRespDTO pageManager(Integer pn, Integer ps, Long storeId, String realName) {
        Page<ManagerDO> page = new Page<>(pn, ps);
        LambdaQueryWrapper<ManagerDO> lambdaQueryWrapper = Wrappers.lambdaQuery(ManagerDO.class)
                .eq(Objects.nonNull(storeId), ManagerDO::getStoreId, storeId)
                .like(Objects.nonNull(realName), ManagerDO::getRealName, realName)
                .eq(ManagerDO::getDelFlag, DelFlag.present);
        Page<ManagerDO> managerDOPage = baseMapper.selectPage(page, lambdaQueryWrapper);

        return ManagerPageRespDTO
                .builder()
                .total(managerDOPage.getTotal())
                .items(managerDOPage.getRecords())
                .build();
    }

    @Override
    public ListRespDTO<ManagerRealNameRespDTO> listManagerRealName() {
        LambdaQueryWrapper<ManagerDO> lambdaQueryWrapper = Wrappers.lambdaQuery(ManagerDO.class)
                .eq(ManagerDO::getDelFlag, DelFlag.present);
        List<ManagerDO> managerDOList = baseMapper.selectList(lambdaQueryWrapper);

        return ListRespDTO
                .<ManagerRealNameRespDTO>builder()
                .total((long) managerDOList.size())
                .items(managerDOList
                        .stream()
                        .map(each -> BeanUtil.toBean(each, ManagerRealNameRespDTO.class))
                        .toList())
                .build();
    }
}
